package com.vanzo.talkie;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.vanzo.bean.Channel;
import com.vanzo.bean.Follower;
import com.vanzo.bean.FollowerDaoUtil;
import com.vanzo.talkie2.R;
import com.vanzo.util.LogUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;


/**
 * Created by tisen on 2018/1/20.
 */

public class TalkieActivity extends BaseActivity implements View.OnClickListener, StateImage.OnClickListener {

    public static final int CHANNEL_CHANGE_RESULT_CODE = 123;

    private static final int TIME_OUT = 10001;
    private static final int CONNECT_SUCCESS = 100;
    private static final int CONNECT_FAIL = 101;
    private static final int SET_CHANNEL_SUCCESS = 102;
    private static final int SET_CHANNEL_FAIL = 103;
    private static final int SET_MODE_SUCCESS = 104;
    private static final int SET_MODE_FAIL = 105;
    private static final int LOGOUT = 106;

    private static final int SET_MIC_SUCCESS = 107;
    private static final int SET_MIC_FAIL = 108;
    private static final int SET_VOL_SUCCESS = 109;
    private static final int SET_VOL_FAIL = 110;
    private static final int SET_FREQ_SUCCESS = 111;
    private static final int SET_FREQ_FAIL = 112;

    private static final int SET_MODE1_SUCCESS = 113;
    private static final int SET_MODE1_FAIL = 114;

    private static final String DEVICE_PATH = "/dev/ttyMT0";
    private static final int DEVICE_BAUD_RATE = 9600;

    private ATHelper atHelper;

    private ImageView mChannel, mRecording, mSetting;
    private ImageButton send;
    private ImageView animation_1, animation_2, animation_3;
    private Animation animation_1_value, animation_2_value, animation_3_value;
    private TextView channelName, tfv, rfv;
    private TextView console;
    private ScrollView conScrollView;
    private AnimationDrawable mMicAnimation;
    private ProgressDialog progressDialog;

    private RecyclerView follower_recycler;
    private ImageView addFollowers;
    private FollowerAdapter followerAdapter;

    private ImageView quit;

    private StateImage power, connect;

    private TextView mic;
    private TextView vol;
    private TextView mode;
    private View fv;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        atHelper = new ATHelper((Application) getApplication());
//        atHelper.open();
        followerDaoUtil = new FollowerDaoUtil(this);
        findViewSetListener();
//        connect();

        onONClick(power);
    }

    private Long tempId;
    private AlertDialog.Builder builder;

    private List<Follower> followers;

    private void findViewSetListener() {

        channelName = (TextView) findViewById(R.id.talkie_channel_title);
        channelName.setText(application.getWork_mode() < 2 ? "安全数字对讲" : "模拟对讲");
        tfv = (TextView) findViewById(R.id.talkie_channel_tfv);
        rfv = (TextView) findViewById(R.id.talkie_channel_rfv);

        quit = (ImageView) findViewById(R.id.talkie_power);

        quit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        console = (TextView) findViewById(R.id.talkie_console);
        conScrollView = (ScrollView) findViewById(R.id.talkie_con_scr);
        atHelper.setLogCall(new ATHelper.logCall() {
            @Override
            public void onLogPut(String log) {
                Message message = new Message();
                message.what = LOGOUT;
                message.obj = log;
                handler.sendMessage(message);
            }
        });
        mChannel = (ImageView) findViewById(R.id.main_channel_img);
        mRecording = (ImageView) findViewById(R.id.main_recording_img);
        mSetting = (ImageView) findViewById(R.id.main_setting_img);
        send = (ImageButton) findViewById(R.id.talkie_send);
        animation_1 = (ImageView) findViewById(R.id.talkie_animation_1);
        animation_2 = (ImageView) findViewById(R.id.talkie_animation_2);
        animation_3 = (ImageView) findViewById(R.id.talkie_animation_3);

        animation_1_value = AnimationUtils.loadAnimation(this, R.anim.circle_1);
        animation_2_value = AnimationUtils.loadAnimation(this, R.anim.circle_2);
        animation_3_value = AnimationUtils.loadAnimation(this, R.anim.circle_3);
        send.setOnTouchListener(minOnTouchListener);
        mChannel.setOnClickListener(this);
        mSetting.setOnClickListener(this);
        mRecording.setVisibility(View.INVISIBLE);
        follower_recycler = (RecyclerView) findViewById(R.id.talkie_follower_list);
        addFollowers = (ImageView) findViewById(R.id.talkie_add_followers);
        followerAdapter = new FollowerAdapter(this);
        followerAdapter.setRecyclerAndAdd(follower_recycler, addFollowers);
        followerAdapter.setClickListener(new FollowerAdapter.ItemClickListener() {
            @Override
            public void onClick(Follower follower) {

            }

            @Override
            public void onLongClick(Follower follower) {
                tempId = follower.getTerminalId();
                if (builder == null) {
                    builder = new AlertDialog.Builder(TalkieActivity.this);
                    builder.setTitle(R.string.menu_dialog_title);
                    builder.setItems(R.array.follower_item_menu, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    });
                }
                builder.create().show();
            }
        });
        follower_recycler.setLayoutManager(new GridLayoutManager(this, 5, GridLayoutManager.VERTICAL, false));
        follower_recycler.setAdapter(followerAdapter);
        addFollowers.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                initFollower();
            }
        });
        followerAdapter.updateFollowers();

        power = (StateImage) findViewById(R.id.talkie_power);
        connect = (StateImage) findViewById(R.id.talkie_connect);

        power.setSrc(R.drawable.power_b, R.drawable.power_r, R.drawable.power_g);
        power.setState(StateImage.STATE_ON);
        power.setStatusClickListener(this);
        connect.setSrc(R.drawable.link_b, R.drawable.disconnect_r, R.drawable.link_g);
        connect.setState(StateImage.STATE_OFF);

        mic = (TextView) findViewById(R.id.talkie_mic);
        vol = (TextView) findViewById(R.id.talkie_vol);
        mic.setOnClickListener(this);
        vol.setOnClickListener(this);
        micPicker = new MicPicker(this, mic, "0");
        volumPicker = new VolumPicker(this, vol, "0");
        micPicker.setPickerSubmit(new MicPicker.PickerSubmit() {
            @Override
            public void submit(int i, String s) {
                atHelper.setMic(s, micCallback);
            }
        });
        volumPicker.setPickerSubmit(new VolumPicker.PickerSubmit() {
            @Override
            public void submit(int i, String s) {
                atHelper.setVolume(s, volCallback);
            }
        });
        fv = findViewById(R.id.talkie_fv);
        fv.setOnClickListener(this);
        tfvPicker = new FrPicker(this, tfv, "发射", application.getUsedChannel().getTfv());
        tfvPicker.setPickListener(new FrPicker.PickListener() {
            @Override
            public void onPick() {
                rfvPicker.show();
            }
        });
        rfvPicker = new FrPicker(this, rfv, "接收", application.getUsedChannel().getRfv());
        rfvPicker.setPickListener(new FrPicker.PickListener() {
            @Override
            public void onPick() {
                atHelper.setChfreq(tfv.getText().toString(), rfv.getText().toString(), freqCallback);
            }
        });
        mode = (TextView) findViewById(R.id.talkie_mode);
        modePicker = new ModePicker(this, mode, "0");
        modePicker.setPickerSubmit(new ModePicker.PickerSubmit() {
            @Override
            public void submit(int i, String s) {
                application.setWork_mode(i);
                atHelper.setChSwitch(i, modeCallback);
            }
        });
    }

    private ATHelper.Callback modeCallback = new ATHelper.Callback() {
        @Override
        public void callback(String result) {
            if (result.contains("+DMOCHSWITCH:0"))
                handler.sendEmptyMessage(SET_MODE1_SUCCESS);
            else if (result.contains("+DMOCHSWITCH:1"))
                handler.sendEmptyMessage(SET_MODE1_FAIL);
        }
    };
    private ATHelper.Callback micCallback = new ATHelper.Callback() {
        @Override
        public void callback(String result) {
            if (result.contains("+DMOSETMIC:0"))
                handler.sendEmptyMessage(SET_MIC_SUCCESS);
            else if (result.contains("+DMOSETMIC:1"))
                handler.sendEmptyMessage(SET_MIC_FAIL);
        }
    };

    private ATHelper.Callback volCallback = new ATHelper.Callback() {
        @Override
        public void callback(String result) {
            if (result.contains("+DMOSETVOLUME:0"))
                handler.sendEmptyMessage(SET_VOL_SUCCESS);
            else if (result.contains("+DMOSETVOLUME:1"))
                handler.sendEmptyMessage(SET_VOL_FAIL);
        }
    };
    private ATHelper.Callback freqCallback = new ATHelper.Callback() {
        @Override
        public void callback(String result) {
            if (result.contains("+DMOSETCHFREQ:0"))
                handler.sendEmptyMessage(SET_FREQ_SUCCESS);
            else if (result.contains("+DMOSETCHFREQ:1"))
                handler.sendEmptyMessage(SET_FREQ_FAIL);
        }
    };

    private int followerSize = 20;

    private FollowerDaoUtil followerDaoUtil;

    private void initFollower() {
        List<Follower> followers = new ArrayList<>();
        for (int i = 0; i < followerSize; i++) {
            followers.add(new Follower(new Long(i), (i < 10) ? "kill" + i : null, false));
        }
        followerDaoUtil.insertMultFollower(followers);
        followerAdapter.updateFollowers();

    }

    private View.OnTouchListener minOnTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                sendUp();
            }
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                sendDown();
            }
            return false;
        }
    };

    private void sendUp() {
        animation_1.setAnimation(null);
        animation_2.setAnimation(null);
        animation_3.setAnimation(null);
        atHelper.setPtt(0, sendUpCallback);
    }

    private void sendDown() {
        animation_1.startAnimation(animation_1_value);
        animation_2.startAnimation(animation_2_value);
        animation_3.startAnimation(animation_3_value);
        atHelper.setPtt(1, sendDownCallback);
    }

    private MicPicker micPicker;
    private VolumPicker volumPicker;
    private FrPicker tfvPicker;
    private FrPicker rfvPicker;
    private ModePicker modePicker;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.main_channel_img:
                Intent intent = new Intent(this, ChannelActivity.class);
                startActivityForResult(intent, 0);
                break;
            case R.id.main_setting_img:
                Intent intent1 = new Intent(this, SettingActivity.class);
                startActivityForResult(intent1, 0);
                break;
            case R.id.talkie_fv:
                tfvPicker.show();
                break;
        }
    }

    @Override
    protected void onStop() {
        if (timeOut != null && timeOut.hasMessages(TIME_OUT)) {
            timeOut.removeMessages(TIME_OUT);
        }
        if (timer != null) {
            timer.cancel();
        }
        super.onStop();
    }

    private void connect() {

        progressDialog = ProgressDialog.show(this, null, "正在初始化", false, true);
        progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                finish();
            }
        });
        timeOut.sendEmptyMessageDelayed(TIME_OUT, 20000);
        timer = new Timer();
        task = new ConnectTask();
        timer.schedule(task, 4000, 2000);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == CHANNEL_CHANGE_RESULT_CODE) {
            setChannel(null);
        }
    }

    private Timer timer;
    private ConnectTask task;

    class ConnectTask extends TimerTask {

        @Override
        public void run() {
            atHelper.connect(new com.vanzo.talkie.ATHelper.Callback() {
                @Override
                public void callback(String result) {
                    if (result.contains("DMOCONNECT")) {
                        timer.cancel();
                        timeOut.removeMessages(TIME_OUT);
                        Message message = new Message();
                        message.what = CONNECT_SUCCESS;
                        message.obj = result;
                        handler.sendMessage(message);
                    }
                }
            });
        }
    }

    private ATHelper.Callback sendUpCallback = new ATHelper.Callback() {
        @Override
        public void callback(String result) {
            if (result.contains("+DMOPTT:0")) {
//                mRecording.setVisibility(View.INVISIBLE);
            }
        }
    };
    private ATHelper.Callback sendDownCallback = new ATHelper.Callback() {
        @Override
        public void callback(String result) {
            if (result.contains("+DMOPTT:0")) {
//                mRecording.setVisibility(View.VISIBLE);
            }
        }
    };

    private Handler timeOut = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            timer.cancel();
            handler.sendEmptyMessage(CONNECT_FAIL);
        }

    };


    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case CONNECT_SUCCESS:
                    setChannel(null);
                    break;
                case CONNECT_FAIL:
                    Toast.makeText(TalkieActivity.this, "初始化失败", Toast.LENGTH_SHORT).show();
                    finish();
                    break;
                case SET_MODE_SUCCESS:
                    atHelper.setChfreq(application.getUsedChannel().getTfv(), application.getUsedChannel().getRfv(), setChfreqCallback);
                    break;
                case SET_MODE_FAIL:
                    Toast.makeText(TalkieActivity.this, "初始化失败", Toast.LENGTH_SHORT).show();
                    finish();
                    break;
                case SET_CHANNEL_SUCCESS:
                    if (progressDialog != null && progressDialog.isShowing())
                        progressDialog.dismiss();
                    Toast.makeText(TalkieActivity.this, "设置频道参数成功", Toast.LENGTH_SHORT).show();
                    break;
                case SET_CHANNEL_FAIL:
                    Toast.makeText(TalkieActivity.this, "设置频道参数失败", Toast.LENGTH_SHORT).show();
                    break;
                case LOGOUT:
                    String log = (String) msg.obj;
                    console.append(log);
                    conScrollView.fullScroll(ScrollView.FOCUS_DOWN);
                    break;
                case SET_MIC_SUCCESS:
                    Toast.makeText(TalkieActivity.this, "设置MIC增益成功", Toast.LENGTH_SHORT).show();
                    break;
                case SET_MIC_FAIL:
                    Toast.makeText(TalkieActivity.this, "设置MIC增益失败", Toast.LENGTH_SHORT).show();
                    break;
                case SET_VOL_SUCCESS:
                    Toast.makeText(TalkieActivity.this, "设置音量参数成功", Toast.LENGTH_SHORT).show();
                    break;
                case SET_VOL_FAIL:
                    Toast.makeText(TalkieActivity.this, "设置音量参数失败", Toast.LENGTH_SHORT).show();
                    break;
                case SET_FREQ_SUCCESS:
                    Toast.makeText(TalkieActivity.this, "设置频率成功", Toast.LENGTH_SHORT).show();
                    break;
                case SET_FREQ_FAIL:
                    Toast.makeText(TalkieActivity.this, "设置频率失败", Toast.LENGTH_SHORT).show();
                    break;
                case SET_MODE1_SUCCESS:
                    Toast.makeText(TalkieActivity.this, "设置模式成功", Toast.LENGTH_SHORT).show();
                    channelName.setText(application.getWork_mode() < 2 ? "安全数字对讲" : "模拟对讲");
                    break;
                case SET_MODE1_FAIL:
                    Toast.makeText(TalkieActivity.this, "设置模式失败", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };

    public void setChannel(Long id) {
        if (id != null) {
            application.setUsedId(id);
        }
        Channel channel = application.getUsedChannel();
//        channelName.setText(channel.getTitle());
        tfv.setText(channel.getTfv());
        rfv.setText(channel.getRfv());
        atHelper.setChSwitch(application.getWork_mode(), setChSwitchCallback);

//        atHelper.setChannel(application.isWork_mode(), application.isGbw_mode(), application.isPower_mode(), channel.getTfv(), channel.getRfv(), channel.getTx(), channel.getRx(), channel.getSq(), setChannelCallback);
    }

    private ATHelper.Callback setChSwitchCallback = new ATHelper.Callback() {
        @Override
        public void callback(String result) {
//            LogUtil.put(TalkieActivity.this, result, LogUtil.WARN);
            if (result.contains("+DMOCHSWITCH:0")) {
                handler.sendEmptyMessage(SET_MODE_SUCCESS);
            } else {
                handler.sendEmptyMessage(SET_MODE_FAIL);
            }
        }
    };

    private ATHelper.Callback setChfreqCallback = new ATHelper.Callback() {
        @Override
        public void callback(String result) {
//            LogUtil.put(TalkieActivity.this, result, LogUtil.WARN);
            if (result.contains("+DMOSETCHFREQ:0")) {
                handler.sendEmptyMessage(SET_CHANNEL_SUCCESS);
            } else {
                handler.sendEmptyMessage(SET_CHANNEL_FAIL);
            }
        }
    };

    private ATHelper.Callback setChannelCallback = new ATHelper.Callback() {
        @Override
        public void callback(String result) {
//            LogUtil.put(TalkieActivity.this, result, LogUtil.WARN);
            if (result.contains("DMOSETGROUP:0")) {
                handler.sendEmptyMessage(SET_CHANNEL_SUCCESS);
            } else {
                handler.sendEmptyMessage(SET_CHANNEL_FAIL);
            }
        }
    };

    @Override
    protected void onDestroy() {
        atHelper.close();
        atHelper.interrupt();
        application.closeSerialPort();
        super.onDestroy();
    }

    private boolean isPttKeyDown = false;
    private boolean isPttTimeOut = false;
    private boolean isPttStop = false;
    private static final int PTT_TIME_OUT = 10009;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        LogUtil.put(this, "keyCode = " + keyCode + " | event = " + event, LogUtil.WARN);
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("确定要退出吗？")
                    .setCancelable(true)
                    .setPositiveButton("确定",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                                    int id) {
                                    finish();
                                }
                            });
            AlertDialog alert = builder.create();
            alert.show();
            return true;
        }
        if (keyCode == KeyEvent.KEYCODE_SLASH && !isPttKeyDown) {
            send.setClickable(false);
            isPttKeyDown = true;
            sendDown();
            pttDownHanler.sendEmptyMessageDelayed(PTT_TIME_OUT, 60000);
        }
        if (keyCode == KeyEvent.KEYCODE_SLASH && isPttTimeOut) {
            isPttTimeOut = false;
            isPttStop = true;
            Toast.makeText(this, "超过60s,请松手后重新对讲", Toast.LENGTH_SHORT).show();
            send.setClickable(true);
            sendUp();
        }
        return super.onKeyDown(keyCode, event);
    }

    private Handler pttDownHanler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            isPttTimeOut = true;
        }
    };

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_SLASH) {
            pttDownHanler.removeMessages(PTT_TIME_OUT);
            if (isPttStop) {
                isPttStop = false;
                isPttKeyDown = false;
            } else {
                send.setClickable(true);
                isPttKeyDown = false;
                sendUp();
            }
        }
        if (keyCode == KeyEvent.KEYCODE_POUND) {
            LogUtil.put(this, "KEYCODE_POUND", LogUtil.WARN);
        }
        return super.onKeyUp(keyCode, event);
    }

    @Override
    public void onONClick(View view) {
        atHelper.open();
        power.setState(StateImage.STATE_OFF);
        connect();
    }

    @Override
    public void onOFFClick(View view) {
        atHelper.close();
        power.setState(StateImage.STATE_ON);
        console.setText("");
        timer.cancel();
    }
}
